package mcp

import (
	"bufio"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"

	"mysql-mcp-server-go/internal/database"
	"mysql-mcp-server-go/internal/tools"
	"mysql-mcp-server-go/pkg/logger"
)

// Server MCP服务器结构体
type Server struct {
	db          *database.DB
	toolManager tools.ToolManagerInterface
	logger      logger.Logger
	ctx         context.Context
	cancel      context.CancelFunc
}

// NewServer 创建新的MCP服务器
func NewServer(db *database.DB, logger logger.Logger) *Server {
	ctx, cancel := context.WithCancel(context.Background())
	
	server := &Server{
		db:          db,
		toolManager: tools.New(db),
		logger:      logger,
		ctx:         ctx,
		cancel:      cancel,
	}
	
	// 注册工具
	// server.registerTools() // 暂时注释掉，因为方法不存在
	
	return server
}

// Start 启动MCP服务器
func (s *Server) Start(ctx context.Context) error {
	s.logger.Info("启动MCP服务器")
	
	reader := bufio.NewReader(os.Stdin)
	
	for {
		select {
		case <-ctx.Done():
			s.logger.Info("接收到停止信号，正在关闭MCP服务器")
			return ctx.Err()
		default:
			line, _, err := reader.ReadLine()
			if err != nil {
				if err == io.EOF {
					s.logger.Info("输入流结束，MCP服务器正常退出")
					return nil
				}
				s.logger.WithError(err).Error("读取输入失败")
				return fmt.Errorf("读取输入失败: %w", err)
			}
			
			if len(line) == 0 {
				continue
			}
			
			s.logger.WithField("request_data", string(line)).Debug("接收到请求")
			
			response := s.handleRequest(line)
			if response != nil {
				responseData, err := json.Marshal(response)
				if err != nil {
					s.logger.WithError(err).Error("序列化响应失败")
					continue
				}
				
				s.logger.WithField("response_data", string(responseData)).Debug("发送响应")
				fmt.Println(string(responseData))
			}
		}
	}
}

// handleRequest 处理JSON-RPC请求
func (s *Server) handleRequest(data []byte) interface{} {
	// 解析JSON-RPC请求
	var request JSONRPCRequest
	if err := json.Unmarshal(data, &request); err != nil {
		s.logger.WithError(err).WithField("raw_data", string(data)).Error("解析JSON-RPC请求失败")
		return &JSONRPCResponse{
			JSONRPC: JSONRPCVersion,
			Error: &RPCError{
				Code:    ParseError,
				Message: "解析错误",
				Data:    err.Error(),
			},
		}
	}
	
	s.logger.WithFields(map[string]interface{}{
		"method":     request.Method,
		"request_id": request.ID,
	}).Debug("处理JSON-RPC请求")
	
	// 路由请求到相应的处理器
	switch request.Method {
	case "initialize":
		return s.handleInitialize(request)
	case "tools/list":
		return s.handleToolsList(request)
	case "tools/call":
		return s.handleToolsCall(request)
	case "ping":
		return s.handlePing(request)
	default:
		s.logger.WithField("method", request.Method).Warn("收到未知方法请求")
		return &JSONRPCResponse{
			JSONRPC: JSONRPCVersion,
			ID:      request.ID,
			Error: &RPCError{
				Code:    MethodNotFound,
				Message: fmt.Sprintf("方法未找到: %s", request.Method),
			},
		}
	}
}

// handleInitialize 处理初始化请求
func (s *Server) handleInitialize(request JSONRPCRequest) *JSONRPCResponse {
	var initReq InitializeRequest
	if request.Params != nil {
		if err := json.Unmarshal(request.Params, &initReq); err != nil {
			return &JSONRPCResponse{
				JSONRPC: JSONRPCVersion,
				ID:      request.ID,
				Error: &RPCError{
					Code:    InvalidParams,
					Message: "无效的初始化参数",
					Data:    err.Error(),
				},
			}
		}
	}
	
	s.logger.WithField("client", initReq.ClientInfo.Name).Info("客户端初始化")
	
	response := InitializeResponse{
		ProtocolVersion: "2024-11-05",
		Capabilities: ServerCapabilities{
			Tools: &ToolsCapability{
				ListChanged: false,
			},
			Logging: &LoggingCapability{},
		},
		ServerInfo: ServerInfo{
			Name:    "mysql-mcp-server-go",
			Version: "1.0.0",
		},
	}
	
	return &JSONRPCResponse{
		JSONRPC: JSONRPCVersion,
		ID:      request.ID,
		Result:  response,
	}
}

// handleToolsList 处理工具列表请求
func (s *Server) handleToolsList(request JSONRPCRequest) *JSONRPCResponse {
	tools := s.toolManager.GetAvailableTools()
	
	return &JSONRPCResponse{
		JSONRPC: JSONRPCVersion,
		ID:      request.ID,
		Result: map[string]interface{}{
			"tools": tools,
		},
	}
}

// handleToolsCall 处理工具调用请求
func (s *Server) handleToolsCall(request JSONRPCRequest) *JSONRPCResponse {
	var callReq ToolsCallRequest
	if err := json.Unmarshal(request.Params, &callReq); err != nil {
		s.logger.WithError(err).WithField("request_id", request.ID).Error("解析工具调用参数失败")
		return &JSONRPCResponse{
			JSONRPC: JSONRPCVersion,
			ID:      request.ID,
			Error: &RPCError{
				Code:    InvalidParams,
				Message: "无效的工具调用参数",
				Data:    err.Error(),
			},
		}
	}
	
	s.logger.WithFields(map[string]interface{}{
		"tool":       callReq.Name,
		"request_id": request.ID,
		"arguments":  callReq.Arguments,
	}).Info("开始执行工具调用")
	
	// 执行工具
	result, err := s.toolManager.ExecuteTool(callReq.Name, callReq.Arguments)
	if err != nil {
		s.logger.WithError(err).WithFields(map[string]interface{}{
			"tool":       callReq.Name,
			"request_id": request.ID,
		}).Error("工具执行失败")
		
		return &JSONRPCResponse{
			JSONRPC: JSONRPCVersion,
			ID:      request.ID,
			Result: ToolsCallResponse{
				Content: []Content{{
					Type: "text",
					Text: fmt.Sprintf("工具执行失败: %v", err),
				}},
				IsError: true,
			},
		}
	}
	
	s.logger.WithFields(map[string]interface{}{
		"tool":       callReq.Name,
		"request_id": request.ID,
	}).Info("工具执行成功")

	return &JSONRPCResponse{
		JSONRPC: JSONRPCVersion,
		ID:      request.ID,
		Result: ToolsCallResponse{
			Content: []Content{{
				Type: "text",
				Text: result.Content[0].Text,
			}},
		},
	}
}

// handlePing 处理ping请求
func (s *Server) handlePing(request JSONRPCRequest) *JSONRPCResponse {
	return &JSONRPCResponse{
		JSONRPC: JSONRPCVersion,
		ID:      request.ID,
		Result:  "pong",
	}
}

// ServeHTTP 实现 http.Handler 接口，用于HTTP服务器
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// 设置响应头
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	// 处理预检请求
	if r.Method == "OPTIONS" {
		w.WriteHeader(http.StatusOK)
		return
	}

	// 只接受POST请求
	if r.Method != "POST" {
		w.WriteHeader(http.StatusMethodNotAllowed)
		json.NewEncoder(w).Encode(map[string]string{
			"error": "只支持POST方法",
		})
		return
	}

	// 读取请求体
	body, err := io.ReadAll(r.Body)
	if err != nil {
		s.logger.WithError(err).Error("读取请求体失败")
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]string{
			"error": "读取请求体失败",
		})
		return
	}
	defer r.Body.Close()

	// 解析JSON-RPC请求
	var request JSONRPCRequest
	if err := json.Unmarshal(body, &request); err != nil {
		s.logger.WithError(err).Error("解析JSON-RPC请求失败")
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]string{
			"error": "无效的JSON-RPC请求",
		})
		return
	}

	// 处理请求
	requestData, _ := json.Marshal(request)
	response := s.handleRequest(requestData)

	// 发送响应
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(response); err != nil {
		s.logger.WithError(err).Error("发送响应失败")
	}
}